home *** CD-ROM | disk | FTP | other *** search
/ Mission 3 / Mission 3.zip / Mission 3.iso / texte / 7up_pd / listbox.c < prev    next >
C/C++ Source or Header  |  1998-10-29  |  8KB  |  295 lines

  1. /*****************************************************************************
  2. *
  3. *                                   7UP
  4. *                              Modul: LISTBOX.C
  5. *                            (c) by TheoSoft '94
  6. *
  7. *****************************************************************************/
  8. #include <portab.h>
  9. #include <stdio.h>
  10. #include <aes.h>
  11.  
  12. #include "forms.h"
  13. #include "7up.h"
  14.  
  15. #define MAXENTRIES 5
  16. #define notnull(x) ((x)?(x):1)
  17. #define FLAGS15 0x8000
  18.  
  19. #define Objc_edit(a,b,c,d,e,f) objc_edit(a,b,c,f,e)
  20.  
  21. #define FMD_FORWARD  1
  22. #define FMD_BACKWARD 2
  23. #define FMD_DEFLT    0
  24.  
  25. extern OBJECT *listbox,*divmenu;
  26. extern int windials;
  27.  
  28. typedef struct
  29. {
  30.    int flags;
  31.    int state;
  32.     int retcode;
  33.    char entry[25];
  34.    int dummy;
  35. }
  36. SCROLLENTRY;
  37.  
  38. typedef struct
  39. {
  40.    long count;
  41.    SCROLLENTRY scrollist[100];
  42. }SCROLLIST;
  43.  
  44. static int list_do(OBJECT *fm_tree, int fm_start_fld)
  45. {
  46.    int fm_next_obj,fm_which,fm_cont;
  47.    int fm_mx,fm_my,fm_mb,fm_ks,fm_kr,fm_br;
  48.  
  49.    fm_cont=TRUE;
  50.    while(fm_cont)
  51.    {
  52.       fm_which=evnt_multi(MU_BUTTON,0x02,0x01,0x01,0,0,0,0,
  53.                           0,0,0,0,0,0,NULL,
  54.                                 0, 0,
  55.                           &fm_mx, &fm_my, &fm_mb, &fm_ks, &fm_kr, &fm_br);
  56.       if(fm_which&MU_BUTTON)
  57.       {
  58.          fm_next_obj=objc_find(fm_tree,ROOT,MAX_DEPTH,fm_mx,fm_my);
  59.          if(fm_next_obj==-1)
  60.          {
  61.             fm_cont=FALSE;
  62.             fm_next_obj=0;
  63.          }
  64.          else
  65.             fm_cont=form_button(fm_tree,fm_next_obj,fm_br,&fm_next_obj);
  66.       }
  67.    }
  68.    return(fm_next_obj);
  69. }
  70.  
  71. static void setsliderpos(OBJECT *tree, int item, int pos)
  72. {
  73.    long oldpos;
  74.    oldpos=tree[item-1].ob_height-tree[item].ob_height;
  75.    tree[item].ob_y=(int)(oldpos*(long)pos/1000L);
  76. }
  77.  
  78. static void _objc_update(OBJECT *tree, int obj, int depth)
  79. {
  80.     int obx,oby;
  81.     objc_offset(tree,obj,&obx,&oby);
  82.     /* einen Pixel weniger, bei depth==0 */
  83.     objc_draw(tree,obj,depth,obx,oby,
  84.         tree[obj].ob_width-(depth?0:1),tree[obj].ob_height);
  85. }
  86.  
  87. static void _form_write(OBJECT *tree, int item, char *string, int modus)
  88. {
  89.     strcpy(tree[item].ob_spec.tedinfo->te_ptext,string);
  90.     if(modus)
  91.         _objc_update(tree,item,0);
  92. }
  93.  
  94. static void _listbox_fill(OBJECT *tree, SCROLLIST *liste, long firstentry)
  95. {
  96.     int i, slider;
  97.     
  98.    for(i=0; i<MAXENTRIES; i++)       
  99.    {
  100.       tree[i+ROOT+1].ob_state =
  101.          liste->scrollist[firstentry+i].state;
  102.       _form_write(tree,i+ROOT+1,liste->scrollist[firstentry+i].entry,TRUE);
  103.    }
  104.    /* liste->count > MAXENTRIES. Keine Division durch null. */
  105.    slider = firstentry*1000/max(1,liste->count-MAXENTRIES);
  106.    setsliderpos(tree,9,slider);
  107.    objc_update(tree,8,MAX_DEPTH);
  108. }
  109.  
  110. static int _listbox_hndl(OBJECT *tree, SCROLLIST *liste)
  111. {
  112.    int  ret, boxw, boxh, i, x, y, mx, my, exit_obj, slider, actentry=0, done=FALSE;
  113.    long firstentry=0;
  114.  
  115.    if(!tree)
  116.       return(-1);
  117.  
  118.    if(!liste)
  119.       return(-2);
  120.  
  121.    if(liste->count <= 0)
  122.       return(-3);
  123.  
  124.    if(liste->count > MAXENTRIES) /* bei mehr Einträgen Selektion positionieren */
  125.       for(i=0; i<liste->count; i++)
  126.          if(liste->scrollist[i].state & SELECTED)
  127.          {
  128.             firstentry = i-2; /* Eintrag positionieren */
  129.             if(firstentry > liste->count-MAXENTRIES)
  130.                firstentry = liste->count-MAXENTRIES;
  131.             if(firstentry < 0)
  132.                firstentry = 0;
  133.             break;
  134.          }
  135.  
  136.    for(i=0; i<MAXENTRIES; i++)       
  137.    {
  138.       tree[i+ROOT+1].ob_state =
  139.          liste->scrollist[firstentry+i].state;
  140.       form_write(tree,i+ROOT+1,liste->scrollist[firstentry+i].entry,FALSE);
  141.    }
  142.  
  143.    for(i=0; i<MAXENTRIES; i++) /* alles verstecken, was nicht da ist */
  144.       if(!*liste->scrollist[i].entry)
  145.          tree[i+ROOT+1].ob_flags |= HIDETREE;
  146.  
  147.    graf_handle(&boxw,&boxh,&ret,&ret);
  148.    tree[9].ob_height=max(boxh,MAXENTRIES*tree[8].ob_height/max(MAXENTRIES,liste->count));
  149.    setsliderpos(tree,9,0);
  150.  
  151.    i=(firstentry*1000L)/max(1,liste->count-MAXENTRIES);
  152.    i=min(i,1000);
  153.    i=max(0,i);
  154.    setsliderpos(tree,9,i);
  155.  
  156.    form_open(tree,0);
  157.    do
  158.    {
  159.       exit_obj=list_do(tree,0);
  160.       if(exit_obj & 0x8000) /* Doppelklick */
  161.       {
  162.          switch(exit_obj &= 0x7FFF) /* MSB weg */
  163.          {
  164.             case 6:
  165.                if(firstentry>0)
  166.                {
  167.                   firstentry=0;
  168.                         _listbox_fill(tree, liste, firstentry);
  169.                }
  170.                break;
  171.             case 7:
  172.                if(firstentry < liste->count-MAXENTRIES)
  173.                {
  174.                    firstentry = liste->count-MAXENTRIES;
  175.                         _listbox_fill(tree, liste, firstentry);
  176.                }
  177.                     break;
  178. /*
  179.             case ROOT+1:
  180.             case ROOT+2:
  181.             case ROOT+3:
  182.             case ROOT+4:
  183.             case ROOT+5:
  184.                actentry = firstentry + exit_obj - 1;
  185.                done = TRUE;
  186.                break;
  187. */
  188.          }
  189.       }
  190.       else
  191.       {
  192.          switch(exit_obj)
  193.          {
  194.             case ROOT:
  195.                done = TRUE;
  196.                break;
  197.             case 6:
  198.                if(firstentry>0)
  199.                {
  200.                   firstentry--;
  201.                         _listbox_fill(tree, liste, firstentry);
  202.                }
  203.                break;
  204.             case 7:
  205.                if(firstentry < liste->count-MAXENTRIES)
  206.                {
  207.                   firstentry++;
  208.                         _listbox_fill(tree, liste, firstentry);
  209.                }
  210.                break;
  211.             case 8:
  212.                objc_offset(tree,9,&x,&y);
  213.                graf_mkstate(&mx,&my,&i,&i);
  214.                if(my < y)
  215.                {
  216.                   if((firstentry -= MAXENTRIES) < 0)
  217.                      firstentry = 0;
  218.                }
  219.                if(my > y)
  220.                {
  221.                   if((firstentry += MAXENTRIES) > (liste->count-MAXENTRIES))
  222.                      firstentry = liste->count-MAXENTRIES;
  223.                }
  224.                     _listbox_fill(tree, liste, firstentry);
  225.                break;
  226.             case 9:
  227.                graf_mouse(FLAT_HAND, NULL);
  228.                slider=graf_slidebox(tree, exit_obj-1, exit_obj, 1);
  229.                graf_mouse(ARROW, NULL);
  230.                firstentry = (liste->count-MAXENTRIES) * slider/1000;
  231.                     _listbox_fill(tree, liste, firstentry);
  232.                break;
  233.             case ROOT+1:
  234.             case ROOT+2:
  235.             case ROOT+3:
  236.             case ROOT+4:
  237.             case ROOT+5:
  238.                actentry = firstentry + exit_obj - 1;
  239.                done = TRUE;
  240.                break;
  241.          }
  242.       }
  243.    }
  244.    while(!done);
  245.    form_close(tree,exit_obj,0);
  246.  
  247.    for(i=0; i<MAXENTRIES; i++)
  248.    {
  249.       tree[i+ROOT+1].ob_flags &= ~HIDETREE;
  250.       tree[i+ROOT+1].ob_state &= ~SELECTED;
  251.    }
  252.  
  253.     if(exit_obj>ROOT)
  254.     {
  255.        for(i=0; i<liste->count; i++)
  256.           liste->scrollist[i].state &= ~SELECTED;
  257.        liste->scrollist[actentry].state |= SELECTED;
  258.     }
  259.    
  260.    return(exit_obj==ROOT?-1:liste->scrollist[actentry].retcode);
  261. }
  262.  
  263. int listbox_hndl(OBJECT *tree, int item, SCROLLIST *liste)
  264. {
  265.     int exit_obj, x, y, ret, boxw, boxh;
  266.     
  267.    graf_handle(&boxw,&boxh,&ret,&ret);
  268.    objc_offset(tree,item,&x,&y);
  269.    listbox->ob_x=x;
  270.    listbox->ob_y=y+boxh+1;
  271.    listbox->ob_type|=(113<<8); /*LTMF ausschalten*/
  272.    if(liste->count<=MAXENTRIES)
  273.    {
  274.        listbox->ob_width-=(2*boxw+1);
  275.        listbox[6].ob_flags|=HIDETREE;
  276.        listbox[7].ob_flags|=HIDETREE;
  277.        listbox[8].ob_flags|=HIDETREE;
  278.     }
  279. /*
  280.     listbox->ob_flags|=FLAGS15; /* kein Windial!!!, weil kein Handle mehr frei*/
  281. */
  282.    exit_obj=_listbox_hndl(listbox,liste);
  283.    if(liste->count<=MAXENTRIES)
  284.    {
  285.        listbox->ob_width+=(2*boxw+1);
  286.        listbox[6].ob_flags&=~HIDETREE;
  287.        listbox[7].ob_flags&=~HIDETREE;
  288.        listbox[8].ob_flags&=~HIDETREE;
  289.     }
  290.     if(!windials)
  291.         objc_draw(tree,ROOT,MAX_DEPTH,listbox->ob_x-1,listbox->ob_y-1,
  292.            listbox->ob_width+4,listbox->ob_height+4);
  293.    return(exit_obj);
  294. }
  295.